#include <iostream>
#include <vector>
#include <cmath>
#include "Nurbs.h"

using namespace std;


// Constructeur
Nurbs::Nurbs(vector< vector<double> > Coord, vector< vector<double> > Vec, int deg) 
{
	int i ;

	tab.resize(Vec.size()) ;
	// Retourne un vecteur qui pointe sur la classe B_spline
	for (i=0 ; i<Vec.size() ; i++)
	{
		tab[i]=new B_spline(Coord,Vec[i],deg) ;
	}
}

// Destructeur
Nurbs::~Nurbs()
{
	// Destruction des classes B_spline pointes
}
/*
vector<double> Nurbs::basisfun(int const&i,double const&u,int const&p,std::vector<double> const&U)
{
		/* INPUT:
      i - knot span  ( from FindSpan() )
      u - parametric point
      p - spline degree
      U - knot sequence
		OUTPUT:
      N - Basis functions vector[p+1]

		Algorithm A2.2 from 'The NURBS BOOK' pg70. */
/*
		int j,r;
		double saved, temp;
		std::vector<double> left(p+1) ;
		std::vector<double> right(p+1) ;
		std::vector<double> N ;

		N.resize(p+1) ;
		N[0] = 1.0;
		for (j = 1; j <= p; j++)
		{
			left[j]  = u - U[i+1-j];
			right[j] = U[i+j] - u;
			saved = 0.0;
			for (r = 0; r < j; r++)
			{
				temp = N[r] / (right[r+1] + left[j-r]);
				N[r] = saved + right[r+1] * temp;
				saved = left[j-r] * temp;
			}
			N[j] = saved;
		}
		return N ;
}
	void affiche_basisfun(std::vector<double> const&N)
{	
	int i ;

	cout << "Affichage Vecteur" << endl ;
	for (i=0;i<N.size();i++)
	{
		cout << N[i] << " " ; 
	}
	cout << endl ;
}*/
/*
void Nurbs::bspkntins(int const&d , std::vector<vector<double> > const&c , std::vector<double> const&k , std::vector<double> const&u )
{
		/* INPUT
		d	- Degree of the B-Spline.
		c	- Control points, matrix of size (dim,nc).
		k	- Knot sequence, row vector of size nk.
		u	- Row vector of knots to be inserted, size nu
		OUTPUT:
		ic	- Control points of the new B-Spline, of size (dim,nc+nu)
		ik	- Knot vector of the new B-Spline, of size (nk+nu)
		Algorithm A2.2 from 'The NURBS BOOK' pg70. */
/*
		int ierr = 0;
	 	int q, j, l ,nk, i, s ;
		int nc, nu, mc, n, r, ind ;
		int m, a, b ;
		double alfa;
		//std::vector<vector<double> > c ;
		std::vector<double> ik ;
		std::vector<vector<double> > ic ;
		mc = c.size() ;
		nc = c[0].size() ;

		//ic=vector<vector<double> >[mc][nc+nu] ;
		//ik=new double[nk+nu] ;
		n = nc - 1;
		r = nu - 1;

		m = n + d + 1;
		a = findspan(n, d, u[0], k);
		b = findspan(n, d, u[r], k);
		b=b++;

		for (q = 0; q < mc; q++)
		{
			for (j=0;j<=a-d;j++)
			{
			ic[q][j]=c[q][j] ;
			}
			for (j=b-1;j<=n;j++)
			{
			ic[q][j+r+1]=c[q][j] ;
			}
		}
		for (j=0;j<=a;j++)
		{
			ik[j]=k[j] ;
		}
		for (j=b+d;j<=m;j++)
		{
			ik[j+r+1]=k[j] ;
		}
		i=b+d ;
		s=b+d+r ;
		for (j = r ; j>=0; j--)
		{
			while ((u[j]<= k[i])&&(i>a))
			{
				for (q=0;q<m;q++)
				{
					ic[q][s-d-1]=c[q][i-d-1] ;
				}
				ik[s]=k[i] ;
				s=s-1 ;
				i=i-1 ;
			}
			for (q=0;q<mc;q++)
			{
				ic[q][s-d-1]=ic[q][s-d] ;
			}
			for (l=1;l<=d;l++)
			{
				ind=s-d+l ;
				alfa=ik[s+l]-u[j] ;
				if (fabs(alfa ==0.0))
				{
					for (q=0;q<mc;q++)
					{
						ic[q][ind-1]=ic[q][ind] ;
					}
				}
				else
				{
					alfa=alfa/(ik[s+l]-k[i-d+l]) ;
					for (q=0;q<mc;q++)
					{
						ic[q][ind-1]=alfa*ic[q][ind-1]+(1.0-alfa)*ic[q][ind] ;
					}
				}
			}
			ik[s]=u[j] ;
			s=s-1 ;
		}
}*/
/*
int Nurbs::findspan(int const&n, int const&p, double const&u, std::vector<double> const&U)
{
		/* INPUT
      n - number of control points - 1
      p - spline degree
      u - parametric point
      U - knot sequence
      RETURN:
      s - knot span, localisation of the parametric point in the knot sequence
	   Algorithm A2.1 from 'The NURBS BOOK' pg68. *//*
      int s, ou, i, nb_vec;
		bool ok=true ;
		nb_vec=U.size() ;

		i=0 ;
		if (u != U[nb_vec-1])
		{
			while (ok)			
			{
				if ((U[i+1]>u) and (U[i]<=u))
				{
					ok=false ;
					s=i ;
				}
				if (i>=nb_vec)
				{
					ok=false ;
					s=0 ;
				}
				i++ ;
			}
		}
		else
		{
			i=nb_vec ;
			while (ok)
			{
				if ((U[i-1]<u)and(U[i]>=u))
				{
					ok=false ;
					s=i-1 ;
				}
				if (i<=0)
				{
					ok=false ;
					s=0 ;
				}
				i-- ;
			}
		}
      return s ;
}*/

void Nurbs::affiche() 
{
	int i,j,k ;

	for (i=0; i < tab.size(); i++)
	{
		cout << "B_spline numero " << i <<endl ;
		tab[i]->affiche() ;
	}
}

